#include "Game.hh" // 包含游戏头文件，定义了Game类和相关功能 / Include Game header, defines Game class and related functions
#include <fstream> // 包含文件流库，用于读写保存文件 / Include file stream library for reading/writing save files
#include <ctime> // 包含时间库，用于设置随机种子 / Include time library for setting random seed

// 初始化游戏：根据模式（生存或创造）设置玩家、房间和任务
// Initialize game: Set up player, rooms, and quest based on mode (survival or creative)
void Game::initializeGame(int mode) {
    srand(static_cast<unsigned>(time(0))); // 设置随机种子，使用当前时间，确保每次运行随机数不同 / Set random seed using current time to ensure different random numbers each run
    if (mode == 1) { // 如果是创造模式（mode == 1） / If creative mode (mode == 1)
        player = new Character("Creator", "A world-shaping adventurer", 1000, 1000, 50, 50, true); // 创建玩家：名字“Creator”，高生命值、无敌 / Create player: name "Creator", high health, invincible
        player->addToInventory(new Item("Diamond Sword", "A razor-sharp diamond sword", 15, 0, 0)); // 给玩家添加钻石剑（+15攻击） / Add Diamond Sword (+15 attack) to inventory
        player->addToInventory(new Item("Diamond Chestplate", "An indestructible armor", 0, 15, 0)); // 给玩家添加钻石胸甲（+15防御） / Add Diamond Chestplate (+15 defense) to inventory
        player->addToInventory(new Item("Healing Potion", "Restores health", 0, 0, 50)); // 给玩家添加治疗药水（+50生命） / Add Healing Potion (+50 health) to inventory
    } else { // 如果是生存模式（mode == 0） / If survival mode (mode == 0)
        player = new Character("Adventurer", "An explorer in the Minecraft world", 100, 100, 10, 5); // 创建玩家：名字“Adventurer”，普通属性 / Create player: name "Adventurer", normal attributes
        player->addToInventory(new Item("Wooden Sword", "A simple wooden sword", 5, 0, 0)); // 给玩家添加木剑（+5攻击） / Add Wooden Sword (+5 attack) to inventory
    }

    Room* theEnd = new Room("The End: A dark void where the Ender Dragon and Endermen reside."); // 创建The End房间，描述其为末影龙的领域 / Create The End room, described as Ender Dragon's domain
    theEnd->addEnemy(new Character("Ender Dragon", "The overlord of The End", 150, 150, 15, 5)); // 在The End添加末影龙敌人 / Add Ender Dragon enemy to The End
    theEnd->addEnemy(new Character("Enderman", "A teleporting dark creature", 40, 40, 10, 3)); // 在The End添加末影人敌人 / Add Enderman enemy to The End
    rooms.push_back(theEnd); // 将The End房间添加到特殊房间列表 / Add The End room to special rooms list

    currentRoom = new Room(getRoomDescription(x, y)); // 创建当前房间，基于玩家坐标(x,y)的描述 / Create current room based on player's coordinates (x,y)
    stepsToEnd = rand() % 3 + 3; // 随机设置到达The End所需的步数（3到5步） / Randomly set steps to reach The End (3 to 5 steps)
    addMessage("[Turn " + std::to_string(turnCount) + "] Quest: Travel south to find The End and defeat the Ender Dragon!"); // 添加任务消息：向南找到The End并击败末影龙 / Add quest message: Travel south to find The End and defeat Ender Dragon
}

// 保存游戏：将游戏状态写入文件
// Save game: Write game state to a file
void Game::saveGame() {
    std::ofstream file("save.txt"); // 创建输出文件流，打开save.txt文件 / Create output file stream, open save.txt
    if (file.is_open()) { // 如果文件成功打开 / If file opened successfully
        file << player->getHealth() << " " << player->getMaxHealth() << " " // 写入玩家当前生命值和最大生命值 / Write player's current and max health
             << player->getAttack() << " " << player->getDefense() << " " // 写入玩家的攻击力和防御力 / Write player's attack and defense
             << player->isInvincible() << "\n"; // 写入玩家的无敌状态（0或1） / Write player's invincibility status (0 or 1)
        file << player->getInventory().size() << "\n"; // 写入背包中物品的数量 / Write number of items in inventory
        for (const auto* item : player->getInventory()) { // 遍历玩家背包中的每个物品 / Loop through each item in player's inventory
            file << item->name << "\n"; // 写入物品名称 / Write item name
        }
        file << player->getEquippedWeapon() << "\n" << player->getEquippedArmor() << "\n"; // 写入当前装备的武器和盔甲（可能是“None”） / Write currently equipped weapon and armor (may be "None")
        file << x << " " << y << "\n"; // 写入玩家当前坐标(x,y) / Write player's current coordinates (x,y)
        file << stepsToEnd << "\n"; // 写入剩余到达The End的步数 / Write remaining steps to The End
        file.close(); // 关闭文件 / Close the file
    } else { // 如果文件打开失败 / If file failed to open
        addMessage("[Turn " + std::to_string(turnCount) + "] Failed to save game!"); // 添加保存失败的消息 / Add message for save failure
    }
}

// 加载游戏：从文件中恢复游戏状态
// Load game: Restore game state from a file
void Game::loadGame() {
    std::ifstream file("save.txt"); // 创建输入文件流，打开save.txt文件 / Create input file stream, open save.txt
    if (file.is_open()) { // 如果文件成功打开 / If file opened successfully
        unsigned health, maxHealth, attack, defense; // 定义变量存储玩家的生命值、攻击力和防御力 / Define variables for player's health, attack, and defense
        bool inv; // 定义变量存储无敌状态 / Define variable for invincibility status
        if (!(file >> health >> maxHealth >> attack >> defense >> inv)) { // 尝试读取玩家数据 / Try to read player data
            addMessage("[Turn " + std::to_string(turnCount) + "] Failed to load player data, starting new game!"); // 如果读取失败，添加错误消息 / Add error message if read fails
            file.close(); // 关闭文件 / Close file
            initializeGame(0); // 以生存模式重新初始化游戏 / Reinitialize game in survival mode
            return; // 退出函数 / Exit function
        }
        player = new Character("Adventurer", "An explorer in the Minecraft world", 
                              health, maxHealth, attack, defense, inv); // 创建玩家，恢复保存的属性 / Create player with restored attributes

        Room* theEnd = new Room("The End: A dark void where the Ender Dragon and Endermen reside."); // 创建The End房间 / Create The End room
        theEnd->addEnemy(new Character("Ender Dragon", "The overlord of The End", 150, 150, 15, 5)); // 添加末影龙敌人 / Add Ender Dragon enemy
        theEnd->addEnemy(new Character("Enderman", "A teleporting dark creature", 40, 40, 10, 3)); // 添加末影人敌人 / Add Enderman enemy
        rooms.push_back(theEnd); // 将The End添加到特殊房间列表 / Add The End to special rooms list

        size_t invSize; // 定义变量存储背包物品数量 / Define variable for inventory size
        if (!(file >> invSize)) { // 尝试读取背包大小 / Try to read inventory size
            addMessage("[Turn " + std::to_string(turnCount) + "] Failed to load inventory, starting new game!"); // 如果读取失败，添加错误消息 / Add error message if read fails
            delete player; // 释放玩家内存 / Free player memory
            delete theEnd; // 释放The End房间内存 / Free The End room memory
            rooms.clear(); // 清空房间列表 / Clear rooms list
            file.close(); // 关闭文件 / Close file
            initializeGame(0); // 以生存模式重新初始化游戏 / Reinitialize game in survival mode
            return; // 退出函数 / Exit function
        }
        std::string line; // 定义字符串变量存储文件中的一行 / Define string variable to store a line from file
        std::getline(file, line); // 清除换行符 / Clear newline character
        for (size_t i = 0; i < invSize; ++i) { // 遍历背包中的每个物品 / Loop through each item in inventory
            if (!std::getline(file, line)) { // 尝试读取物品名称 / Try to read item name
                addMessage("[Turn " + std::to_string(turnCount) + "] Failed to load items, starting new game!"); // 如果读取失败，添加错误消息 / Add error message if read fails
                delete player; // 释放玩家内存 / Free player memory
                delete theEnd; // 释放The End房间内存 / Free The End room memory
                rooms.clear(); // 清空房间列表 / Clear rooms list
                file.close(); // 关闭文件 / Close file
                initializeGame(0); // 以生存模式重新初始化游戏 / Reinitialize game in survival mode
                return; // 退出函数 / Exit function
            }
            // 根据物品名称恢复背包中的物品 / Restore items in inventory based on name
            if (line == "Wooden Sword") player->addToInventory(new Item("Wooden Sword", "A simple wooden sword", 5, 0, 0)); // 添加木剑 / Add Wooden Sword
            else if (line == "Diamond Sword") player->addToInventory(new Item("Diamond Sword", "A razor-sharp diamond sword", 15, 0, 0)); // 添加钻石剑 / Add Diamond Sword
            else if (line == "Diamond Chestplate") player->addToInventory(new Item("Diamond Chestplate", "An indestructible armor", 0, 15, 0)); // 添加钻石胸甲 / Add Diamond Chestplate
            else if (line == "Healing Potion") player->addToInventory(new Item("Healing Potion", "Restores health", 0, 0, 50)); // 添加治疗药水 / Add Healing Potion
            else if (line == "Bread") player->addToInventory(new Item("Bread", "A villager's gift", 0, 0, 10)); // 添加面包 / Add Bread
            else if (line == "Stick") player->addToInventory(new Item("Stick", "A simple stick", 3, 0, 0)); // 添加木棍 / Add Stick
            else if (line == "Gunpowder") player->addToInventory(new Item("Gunpowder", "Creeper's drop", 0, 0, 0)); // 添加火药 / Add Gunpowder
            else if (line == "Bone") player->addToInventory(new Item("Bone", "Skeleton's drop", 0, 0, 0)); // 添加骨头 / Add Bone
            else if (line == "Crossbow") player->addToInventory(new Item("Crossbow", "Pillager's weapon", 10, 0, 0)); // 添加弩 / Add Crossbow
            else if (line == "Glass Bottle") player->addToInventory(new Item("Glass Bottle", "Witch's drop", 0, 0, 0)); // 添加玻璃瓶 / Add Glass Bottle
            else if (line == "Dragon Egg") player->addToInventory(new Item("Dragon Egg", "Ender Dragon's relic", 0, 0, 0)); // 添加龙蛋 / Add Dragon Egg
            else if (line == "Rotten Flesh") player->addToInventory(new Item("Rotten Flesh", "Zombie's drop", 0, 0, 5)); // 添加腐肉 / Add Rotten Flesh
        }

        if (!std::getline(file, line)) { // 尝试读取装备的武器 / Try to read equipped weapon
            addMessage("[Turn " + std::to_string(turnCount) + "] Failed to load weapon, starting new game!"); // 如果读取失败，添加错误消息 / Add error message if read fails
            delete player; // 释放玩家内存 / Free player memory
            delete theEnd; // 释放The End房间内存 / Free The End room memory
            rooms.clear(); // 清空房间列表 / Clear rooms list
            file.close(); // 关闭文件 / Close file
            initializeGame(0); // 以生存模式重新初始化游戏 / Reinitialize game in survival mode
            return; // 退出函数 / Exit function
        }
        if (line != "None") { // 如果武器不是“None” / If weapon is not "None"
            for (size_t i = 0; i < player->getInventory().size(); ++i) { // 遍历背包 / Loop through inventory
                if (player->getInventory()[i]->name == line) { // 如果找到匹配的武器 / If matching weapon is found
                    player->equipItem(i); // 装备该武器 / Equip the weapon
                    break; // 退出循环 / Exit loop
                }
            }
        }
        if (!std::getline(file, line)) { // 尝试读取装备的盔甲 / Try to read equipped armor
            addMessage("[Turn " + std::to_string(turnCount) + "] Failed to load armor, starting new game!"); // 如果读取失败，添加错误消息 / Add error message if read fails
            delete player; // 释放玩家内存 / Free player memory
            delete theEnd; // 释放The End房间内存 / Free The End room memory
            rooms.clear(); // 清空房间列表 / Clear rooms list
            file.close(); // 关闭文件 / Close file
            initializeGame(0); // 以生存模式重新初始化游戏 / Reinitialize game in survival mode
            return; // 退出函数 / Exit function
        }
        if (line != "None") { // 如果盔甲不是“None” / If armor is not "None"
            for (size_t i = 0; i < player->getInventory().size(); ++i) { // 遍历背包 / Loop through inventory
                if (player->getInventory()[i]->name == line) { // 如果找到匹配的盔甲 / If matching armor is found
                    player->equipItem(i); // 装备该盔甲 / Equip the armor
                    break; // 退出循环 / Exit loop
                }
            }
        }

        if (!(file >> x >> y >> stepsToEnd)) { // 尝试读取坐标和剩余步数 / Try to read coordinates and remaining steps
            addMessage("[Turn " + std::to_string(turnCount) + "] Failed to load position, starting new game!"); // 如果读取失败，添加错误消息 / Add error message if read fails
            delete player; // 释放玩家内存 / Free player memory
            delete theEnd; // 释放The End房间内存 / Free The End room memory
            rooms.clear(); // 清空房间列表 / Clear rooms list
            file.close(); // 关闭文件 / Close file
            initializeGame(0); // 以生存模式重新初始化游戏 / Reinitialize game in survival mode
            return; // 退出函数 / Exit function
        }

        if (stepsToEnd <= 0) currentRoom = rooms[0]; // 如果步数耗尽，设置当前房间为The End / If steps are exhausted, set current room to The End
        else currentRoom = new Room(getRoomDescription(x, y)); // 否则创建基于坐标的房间 / Otherwise create room based on coordinates

        file.close(); // 关闭文件 / Close file
        addMessage("[Turn " + std::to_string(turnCount) + "] Game loaded successfully!"); // 添加加载成功的消息 / Add message for successful load
    } else { // 如果文件打开失败 / If file failed to open
        addMessage("[Turn " + std::to_string(turnCount) + "] No save file found, starting new game!"); // 添加无保存文件的消息 / Add message for no save file
        initializeGame(0); // 以生存模式初始化新游戏 / Initialize new game in survival mode
    }
}